package com.cssw.fyzb.busi.api.turntable;

import com.cssw.fyzb.busi.api.user.GetUserInfo;
import com.cssw.fyzb.busi.service.acct.GzAddPriceService;
import com.cssw.fyzb.busi.service.turntable.TurntableService;
import com.cssw.fyzb.busi.service.user.UserExtService;
import com.cssw.fyzb.core.exception.BizException;
import com.cssw.fyzb.core.model.dodb.*;
import com.cssw.fyzb.core.model.vo.acct.AcctGlobalVo;
import com.cssw.fyzb.busi.service.acct.AcctService;
import com.cssw.fyzb.core.model.vo.turntable.GetInfoVo;
import com.cssw.fyzb.core.model.vo.turntable.TurnResultVo;
import com.ydn.appserver.Action;
import com.ydn.appserver.Request;
import com.ydn.appserver.Response;
import com.ydn.appserver.annotations.Function;
import com.ydn.appserver.annotations.Parameter;
import com.ydn.appserver.annotations.Type;
import com.ydn.dbframe.plugin.activerecord.Db;
import com.ydn.simplelock.SimpleLock;
import com.ydn.simplelock.SimpleLockFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;


/**
 * 抽奖
 * <p>
 * asa
 */
@Function(description = "抽奖", parameters = {
        @Parameter(name = "userId", type = Type.String, description = "用户标识", required = true)
})

@Component
public class Turn implements Action {

    @Autowired
    private AcctService acctService;

    @Autowired
    private UserExtService userExtService;

    @Autowired
    private TurntableService turntableService;

    @Autowired
    private GzAddPriceService gzAddPriceService;

    @Autowired
    private SimpleLockFactory simpleLockFactory;

    private static final Logger logger = LoggerFactory.getLogger(Turn.class);

    @Override
    public Response execute(Request request) throws Exception {
        Long userId = request.getLong("userId");

        // 获取锁
        SimpleLock lock = simpleLockFactory.getLock("USER_" + userId);

        try {
            lock.acquire();

            Acct acct = acctService.queryAcctByUIdAndType(userId, "F");
            BigDecimal balanceFee = acct.getBalanceFee();
            TurntableWin turntableWin = turntableService.getTurnAgainWinLog(userId);
            if (turntableWin == null && balanceFee.compareTo(new BigDecimal(10)) < 0) {
                return Response.fail("余额不足！");
            }
            TurnResultVo turnResultVo = new TurnResultVo();
            turnResultVo.setLogId(0L);
            //获取配置
            List<Turntable> turnConf = turntableService.findAll();
            BigDecimal totalRate = new BigDecimal(0);
            //设置默认值为未中奖
            for (Turntable turntable : turnConf) {
                if (turntable.getType() == "0") {
                    turnResultVo.setTurntableId(turntable.getTurntableId());
                    turnResultVo.setType(turntable.getType());
                    turnResultVo.setTypeVal(turntable.getTypeVal());
                    turnResultVo.setTurntableName(turntable.getTurntableName());
                    turnResultVo.setThumb(turntable.getThumb());
                }
                totalRate = totalRate.add(turntable.getRate());
            }
            BigDecimal currentNumber = new BigDecimal(Math.random() * totalRate.doubleValue());
            BigDecimal rate = new BigDecimal(0);
            for (Turntable turntable :
                    turnConf) {
                rate = rate.add(turntable.getRate());
                if (rate.compareTo(currentNumber) > 0) {
                    turnResultVo.setTurntableId(turntable.getTurntableId());
                    turnResultVo.setType(turntable.getType());
                    turnResultVo.setTypeVal(turntable.getTypeVal());
                    turnResultVo.setTurntableName(turntable.getTurntableName());
                    turnResultVo.setThumb(turntable.getThumb());
                    break;
                }
            }
            //开始转账事务
            Db.tx(() -> {
                String win = "0";
                if (!turnResultVo.getType().equals("0")) {
                    win = "1";
                }
                Long turnLogId = turntableService.addTurnLog(userId, turnResultVo.getTurntableId(), "10", turnResultVo.getTurntableName(), "1", win);
                Long turnWinLogId = 0L;
                if (!turnResultVo.getType().equals("0")) {
                    if (turnResultVo.getType().equals("2")) {
                        turnWinLogId = turntableService.addTurnWinLog(turnLogId, userId, turnResultVo.getTurntableId(), turnResultVo.getType(), turnResultVo.getTurntableName(), turnResultVo.getThumb(), "2");
                    } else {
                        turnWinLogId = turntableService.addTurnWinLog(turnLogId, userId, turnResultVo.getTurntableId(), turnResultVo.getType(), turnResultVo.getTurntableName(), turnResultVo.getThumb(), "1");
                    }

                }
                turnResultVo.setLogId(turnLogId);

                if (turntableWin != null) {
                    turntableService.updateTurnAgainWinLog(turntableWin);
                } else {
                    // 减少余额
                    acctService.minusBalance(userId, "F", new BigDecimal(10), turnLogId.toString(), AcctTradeType.TURN_TASK, BusiType.TURN_TASK, "活动任务-转盘抽奖");
                }
                if (turnResultVo.getType().equals("2")) {
                    // 增加余额
                    acctService.addBalance(userId, "F", new BigDecimal(turnResultVo.getTypeVal()), turnWinLogId.toString(), AcctTradeType.TURN_TASK, BusiType.TURN_TASK, "活动任务-中奖");
                }

                TurntableNumPriceLog numPriceLog = turntableService.getTurnNumPriceLog(userId);

                if (null != numPriceLog) {
                    TurntableNumPrice numPrice = turntableService.getTurnNumPriceByNum(numPriceLog.getNum() + 1);
                    numPriceLog.setNum(numPriceLog.getNum() + 1);
                    if (null != numPrice) {
                        numPriceLog.setPrice(numPrice.getPrice());
                        processGzAddPrice(userId, numPriceLog.getLogId(), numPrice);
                    }
                    turntableService.updateLog(numPriceLog);

                    turnResultVo.setTurnNums(numPriceLog.getNum());
                    turnResultVo.setAddedPrice(numPriceLog.getPrice());
                } else {
                    TurntableNumPrice numPrice = turntableService.getTurnNumPriceByNum(1);
                    if (null != numPrice) {
                        Long logId = turntableService.saveLog(userId, 1, numPrice.getPrice());
                        processGzAddPrice(userId, logId, numPrice);
                        turnResultVo.setAddedPrice(numPrice.getPrice());
                    } else {
                        turntableService.saveLog(userId, 1, BigDecimal.ZERO);
                        turnResultVo.setAddedPrice(BigDecimal.ZERO);
                    }

                    turnResultVo.setTurnNums(1);
                }
                return true;
            });

            turnResultVo.setOneMoreTimes(0);
            turnResultVo.setFBalance(balanceFee.subtract(new BigDecimal(10)));
            if (balanceFee.compareTo(new BigDecimal(20)) < 0) {
                turnResultVo.setCanTurn(false);
            } else {
                turnResultVo.setCanTurn(true);
            }
            return Response.success().put("data", turnResultVo);
        } catch (Exception e) {
            if (e instanceof BizException) {
                BizException be = (BizException) e;
                return Response.fail(be.getErrMsg(), be.getErrCode());
            }
            logger.error("", e);
            return Response.fail("操作异常");
        } finally {
            try {
                lock.release();
            } catch (Exception e) {
                logger.error("", e);
            }
        }
    }

    private void processGzAddPrice(Long userId, Long logId, TurntableNumPrice numPrice) {
        GzAddPrice gzAddPrice = gzAddPriceService.getTodayGzAddPrice(userId, GzAddPrice.TASK_TYPE_TURNTABLE);

        if (null == gzAddPrice) {
            userExtService.addGzAddPrice(userId, numPrice.getPrice());
            gzAddPriceService.addGzAddPrice(userId, numPrice.getPrice(), GzAddPrice.TASK_TYPE_TURNTABLE, logId.toString(), "活动任务");
        } else {
            BigDecimal addPrice = numPrice.getPrice().subtract(gzAddPrice.getPrice());

            //如果没有增值价格，则不更新
            if (addPrice.compareTo(BigDecimal.ZERO) < 1) {
                return;
            }

            userExtService.addGzAddPrice(userId, addPrice);
            gzAddPriceService.updateGzAddPrice(gzAddPrice.getId(), numPrice.getPrice());
        }
    }
}


